<?php
namespace App\Http\Controllers\Dashboard;

use App\Events\Money\DepositEvent;
use App\Events\Money\PrizeDepositEvent;
use App\Events\Money\TransferInEvent;
use App\Events\Money\TransferOutEvent;
use App\Events\Money\WithdrawEvent;
use App\Events\NewUserEvent;
use App\Events\Ticket\BuyEvent;
use App\Events\Ticket\PrizeKycEvent;
use App\Events\Ticket\TicketDepositEvent;
use App\Models\LoanApplication;
use App\Models\LoanTag;
use App\Models\Order;
use App\Models\Org;
use App\Models\User;
use App\Models\UserKyc;
use App\Models\UserMoneyLog;
use App\Models\UserMoneyWithdraw;
use App\Models\UserTicketLog;
use Illuminate\Http\JsonResponse;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Str;

class UserController extends BaseController
{

    /**
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function index(Request $request) {

        $pageSize = (int) $request->input('pageSize', 20);
        $query = User::ofOrgCode($request->user())->with('parent')->whereNotNull('org_code')->with('org')->orderByDesc('id');

        if ($queryName = $request->input('name')) {
            $query->where('name', 'like', "%{$queryName}%");
        }
        if ($queryParent = $request->input('parent')) {
            $ids = User::where('name','like',"%$queryParent%")->orWhere('mobile','like',"%$queryParent%")->pluck('id');
            if(count($ids)){
                $query->whereIn('parent_id',$ids);
            }
        }
        if ($orgCode = $request->org_code) {
            $query->where('org_code', $orgCode);
        }

        if ($queryMobile = $request->input('mobile')) {
            $query->where('mobile', 'like', "%{$queryMobile}%");
        }

        if ($kyc = $request->input('kyc') ) {
            $query->where('kyc', intval($kyc));
        }

        return response()->json($query->paginate($pageSize));
    }

    /**
     * 非机构用户列表
     *
     * @param Request $request
     * @return JsonResponse
     */
    public function appUser(Request $request) {

        $pageSize = (int) $request->input('pageSize', 20);
        $query = User::ofOrgCode($request->user())->with('parent')->whereNull('org_code')->orderByDesc('id');

        if ($queryName = $request->input('name')) {
            $query->where('name', 'like', "%{$queryName}%");
        }

        if ($queryParent = $request->input('parent')) {
            $ids = User::where('name','like',"%$queryParent%")->orWhere('mobile','like',"%$queryParent%")->pluck('id');
            if(count($ids)){
                $query->whereIn('parent_id',$ids);
            }
        }

        if ($kyc = $request->input('kyc') ) {
            $query->where('kyc', intval($kyc));
        }

        if ($queryMobile = $request->input('mobile')) {
            $query->where('mobile', 'like', "%{$queryMobile}%");
        }

        return response()->json($query->paginate($pageSize));
    }

    public function saveInviter(Request $request)
    {
        $user_id = $request->input('user_id');
        $parent_id = $request->input('parent_id');
        $query = DB::table('users')->where('id',$user_id)->update(['parent_id'=>$parent_id]);
       return response()->json($query);

    }



    public function createUser(Request $request) {
        $validator = Validator::make($request->all(), [
            'mobile' => 'required',
            'name' => 'required',
        ], [
            'required' => ':attribute 必填',
        ]);

        if ($validator->stopOnFirstFailure()->fails()) {
            return response()->json([
                'code' => 1,
                'msg' => $validator->errors()->first(),
                'data' => null
            ]);
        }

        $admin = $request->user();
        $admin_id = $admin->id;

        $user = User::where('name', $request->name)->first();
        if (!empty($user)) {
            return response()->json([
                'msg' => "用户名已经被注册",
                'code' => 500,
                'data' => null,
            ]);
        }

        $user = User::where('mobile', $request->mobile)->first();
        if (!empty($user)) {
            return response()->json([
                'msg' => "手机号已经被注册",
                'code' => 500,
                'data' => null,
            ]);
        }
        $model = new User();
        $model->name = (string)$request->name;
        $model->mobile = (string) $request->mobile;
        $model->org_root = 200;
        $model->org_code = null;
        $model->gender = (int) $request->gender;
        $model->status = 1;
        $model->role = '';
        $model->kyc = 0;
        $model->money = 0;
        $model->ticket = 0;
        $model->password = Hash::make(123456);
        $model->invite_code = Str::random(8);
        $model->parent_id  = $admin_id;
        if ($model->save()) {
            NewUserEvent::dispatch($model);
            return response()->json([
                'code' => 0,
                'msg' => '注册成功',
                'data' => [],
            ]);
        } else {
            return response()->json([
                'code' => 1,
                'msg' => '注册失败',
                'data' => null
            ]);
        }
    }




    /**
     * @param Request $request
     * @param $id
     * @return JsonResponse
     */
    public function detail(Request $request, $id)
    {
        $user = User::ofOrgCode($request->user())->find($id);
        if (empty($user)) {
            return response()->json([
                'code' => 1,
                'msg' => '没有数据权限',
                'data' => null
            ]);
        }

        $user->load(['org']);
        return response()->json([
            'code' => 0,
            'msg' => 'ok',
            'data' => $user
        ]);
    }

    /**
     * @param Request $request
     * @param $id
     * @return JsonResponse
     */
    public function loan(Request $request, $id) {
        $user = User::ofOrgCode($request->user())->find($id);
        if (empty($user)) {
            return response()->json([
                'code' => 1,
                'msg' => '没有数据权限',
                'data' => null
            ]);
        }

        $pageSize = (int) $request->input('pageSize', 20);
        return response()->json([
            'code' => 0,
            'msg' => 'ok',
            'data' => LoanApplication::where('user_id', $id)
                ->orderByDesc('id')->paginate($pageSize)
        ]);
    }

    /**
     * @param Request $request
     * @param $id
     * @return JsonResponse
     */
    public function kyc(Request $request, $id) {
        $user = User::ofOrgCode($request->user())->find($id);
        if (empty($user)) {
            return response()->json([
                'code' => 1,
                'msg' => '没有数据权限',
                'data' => null
            ]);
        }

        $user->kycInfo->address_tag = $user->kycInfo->address_tag ? json_decode($user->kycInfo->address_tag) : [];

        return response()->json([
            'code' => 0,
            'msg' => 'ok',
            'data' => [
                'kyc' => $user->kycInfo,
                'user' => $user
            ]
        ]);
    }

    /**
     * @param Request $request
     * @param $id
     * @return JsonResponse|void
     */
    public function auditKyc(Request $request, $id)
    {
        if (!in_array($request->pass, ['yes', 'no'])) {
            return response()->json([
                'code' => 1,
                'msg' => '参数不正确',
                'data' => null
            ]);
        }

        $user = User::ofOrgCode($request->user())->find($id);
        if (empty($user)) {
            return response()->json([
                'code' => 1,
                'msg' => '没有数据权限',
                'data' => null
            ]);
        }

        if ($user->kyc == 2) {
            return response()->json([
                'code' => 1,
                'msg' => '已经认证成功',
                'data' => null
            ]);
        }

        if ($request->pass == 'yes') {
            $user->kyc = 2;
        } else {
            $user->kyc = -1;
        }

        $model = UserKyc::where('user_id', $id)->first();
        $model->address_tag = $request->tag?json_encode($request->tag,JSON_UNESCAPED_UNICODE):null;
        $model->save();
        if ($user->save()) {
            // 实名认证通过后给推荐人奖励, 2次抢单机会
            if ($user->kyc == 2 && !empty($user->parent)) {
                $user->parent->ticket += 20;
                $user->parent->save();
                PrizeKycEvent::dispatch($user->parent_id, 20,  sprintf("%s 实名认证成功", $user->name));
            }

            return response()->json([
                'code' => 0,
                'msg' => '保存成功',
                'data' => $user
            ]);
        } else {
            return response()->json([
                'code' => 1,
                'msg' => '保存失败',
                'data' => null
            ]);
        }
    }

    /**
     * @param Request $request
     * @param $id
     * @return JsonResponse
     */
    public function money(Request $request, $id) {
        $user = User::ofOrgCode($request->user())->find($id);
        if (empty($user)) {
            return response()->json([
                'code' => 1,
                'msg' => '没有数据权限',
                'data' => null
            ]);
        }

        $pageSize = (int) $request->input('pageSize', 20);
        return response()->json([
            'code' => 0,
            'msg' => 'ok',
            'data' => UserMoneyLog::where('user_id', $id)
                ->orderByDesc('id')->paginate($pageSize)
        ]);
    }

    /**
     * @param Request $request
     * @param $id
     * @return JsonResponse
     */
    public function ticket(Request $request, $id) {
        $user = User::ofOrgCode($request->user())->find($id);
        if (empty($user)) {
            return response()->json([
                'code' => 1,
                'msg' => '没有数据权限',
                'data' => null
            ]);
        }

        $pageSize = (int) $request->input('pageSize', 20);
        return response()->json([
            'code' => 0,
            'msg' => 'ok',
            'data' => UserTicketLog::where('user_id', $id)
                ->orderByDesc('id')->paginate($pageSize)
        ]);
    }

    /**
     * @param Request $request
     * @param $id
     * @return JsonResponse
     */
    public function edit(Request $request, $id) {
        $user = User::ofOrgCode($request->user())->find($id);
        if (empty($user)) {
            return response()->json([
                'code' => 1,
                'msg' => '没有数据权限',
                'data' => null
            ]);
        }

        if (User::where('mobile', $request->mobile)->where('id', "<>", $id)->count()) {
            return response()->json([
                'code' => 1,
                'msg' => '手机号码已被使用',
                'data' => null
            ]);
        }

        // 修改用户机构, 非超级用户只能将用户修改为当前或者下级机构
        if ($request->org && $request->org['org_code']  && $request->org['org_code'] != $user->org_code) {
            if(!$request->user()->isSupper()) {
                // 当前登录用户的机构号
                $operator_org_code = $request->user()->org_code;
                $new_org_code = $request->org['org_code'];
                if (!str_starts_with($new_org_code, $operator_org_code)) {
                    return response()->json([
                        'code' => 1,
                        'msg' => '无权更改用户到指定机构',
                        'data' => null
                    ]);
                }
            }
            $user->org_code = (string) $request->org['org_code'];
        }

        if (!is_null($request->name)) {
            $user->name = (string)$request->name;
        }

        if (!is_null($request->mobile)) {
            $user->mobile = (string)$request->mobile;
        }

        if (!is_null($request->gender)) {
            $user->gender = (int)$request->gender;
        }

        if (!is_null($request->status)) {
            $user->status = (int)$request->status;
        }

        if (!is_null($request->role)) {
            $user->role = (string)$request->role;
        }

        if ($user->save()) {
            return response()->json([
                'code' => 0,
                'msg' => '保存成功',
                'data' => $user
            ]);
        } else {
            return response()->json([
                'code' => 1,
                'msg' => '保存失败',
                'data' => null
            ]);
        }
    }

    /**
     * @param Request $request
     * @return JsonResponse
     * @throws \Exception
     */
    public function create(Request $request) {

        $org_code = $request->org && $request->org['org_code'] ? $request->org['org_code'] : '';

        $org = Org::ofOrgCode($request->user())->where('org_code', $org_code)->first();
        if (empty($org)) {
            return response()->json([
                'code' => 1,
                'msg' => '没有数据权限',
                'data' => null
            ]);
        }

        if (User::where('mobile', $request->mobile)->count()) {
            return response()->json([
                'code' => 1,
                'msg' => '手机号码已被使用',
                'data' => null
            ]);
        }

        if (User::where('name', $request->name)->count()) {
            return response()->json([
                'code' => 1,
                'msg' => '用户名已被使用',
                'data' => null
            ]);
        }

        if(!$request->user()->isSupper()) {
            // 当前登录用户的机构号
            $operator_org_code = $request->user()->org_code;
            $new_org_code = $org->org_code;
            if (!str_starts_with($new_org_code, $operator_org_code)) {
                return response()->json([
                    'code' => 1,
                    'msg' => '无权机构权限',
                    'data' => null
                ]);
            }
        }

        $model = new User();
        $model->name = (string)$request->name;
        $model->mobile = (string) $request->mobile;
        $model->org_root = $org->org_root;
        $model->org_code = $org->org_code;
        $model->gender = (int) $request->gender;
        $model->status = (int) $request->status;
        $model->role = (string) $request->role;
        $model->kyc =0;
        $model->money = 0;
        $model->ticket = 0;
        $model->password = Hash::make(Str::random(6));
        $model->invite_code = Str::random(8);

        if ($model->save()) {
            return response()->json([
                'code' => 0,
                'msg' => '保存成功',
                'data' => $model
            ]);
        } else {
            return response()->json([
                'code' => 1,
                'msg' => '保存失败',
                'data' => null
            ]);
        }
    }


    /**
     * 转出资金到指定账户
     *
     * @param Request $request
     * @return JsonResponse
     */
    public function  transferMoney(Request $request) {
        $validator = Validator::make($request->all(), [
            'amount' => 'required|min:1',
            'toUser' => 'required|min:1',
        ], [
            'required' => ':attribute 必填',
        ]);

        if ($validator->stopOnFirstFailure()->fails()) {
            return response()->json([
                'code' => 1,
                'msg' => $validator->errors()->first(),
                'data' => null
            ]);
        }

        $fromUser = $request->user();
        $toUser = User::find($request->toUser);
        if(empty($toUser)) {
            return response()->json([
                'code' => 1,
                'msg' => sprintf("目标账户不存在"),
                'data' => null
            ]);
        } else if($fromUser->id == $toUser->id) {
            return response()->json([
                'code' => 1,
                'msg' => sprintf("目标账户不能为自己"),
                'data' => null
            ]);
        }

        $amount = (float) $request->amount;

        if ($fromUser->free_money < $amount) {
            if ($fromUser->free_money < $fromUser->money) {
                $msg = sprintf("账户可用余额不够! 当前余额为%s，可用%s", $fromUser->money, $fromUser->free_money);
            } else {
                $msg = sprintf("账户余额不够! 当前余额为%s", $fromUser->money);
            }

            return response()->json([
                'code' => 1,
                'msg' => $msg,
                'data' => null
            ]);
        }

        $fromUser->money = $fromUser->money - $amount;
        $toUser->money =  $toUser->money + $amount;
        Log::info(sprintf("资金下拨，From %s To %s, 额度 %s", $fromUser->mobile, $toUser->mobile, $amount));
        if($fromUser->save() && $toUser->save()) {

            TransferOutEvent::dispatch($fromUser->id, -$amount, sprintf("资金分拨给 %s", $toUser->name));
            TransferInEvent::dispatch($toUser->id, $amount, sprintf("来自%s的资金分拨", $fromUser->name));

            return response()->json([
                'code' => 0,
                'msg' => sprintf("操作成功"),
                'data' => null
            ]);
        } else {
            return response()->json([
                'code' => 1,
                'msg' => sprintf("操作失败"),
                'data' => null
            ]);
        }
    }

    /**
     * 充值余额
     *
     * @param Request $request
     * @return JsonResponse
     */
    public function rechargeMoney(Request $request) {
//        $validator = Validator::make($request->all(), [
//            'amount' => 'required|min:1',
//            'toUser' => 'required|min:1',
//        ], [
//            'required' => ':attribute 必填',
//        ]);
//        if ($validator->stopOnFirstFailure()->fails()) {
//            return response()->json([
//                'code' => 1,
//                'msg' => $validator->errors()->first(),
//                'data' => null
//            ]);
//        }

        $fromUser = $request->user();
        $toUser = User::find($request->toUser);
        if(empty($toUser)) {
            return response()->json([
                'code' => 1,
                'msg' => sprintf("目标账户不存在"),
                'data' => null
            ]);
        }

        $amount = (float) $request->amount;
        $amountRemove = (float) $request->amountRemove;
        $toUser->money =  $toUser->money + $amount - $amountRemove;
        if($toUser->save()) {
            if($amountRemove==0){
                DepositEvent::dispatch($toUser->id, $amount, sprintf("经办人 %s", $fromUser->name));
                // 充值提成
                if (!empty($toUser->parent)) {
                    $prize = round($amount * 0.1, 2, PHP_ROUND_HALF_DOWN);
                    $toUser->parent->money += $prize;
                    $toUser->parent->save();
                    PrizeDepositEvent::dispatch($toUser->parent_id, $prize,  sprintf("%s 充值提成", $toUser->name));
                }
            }

            return response()->json([
                'code' => 0,
                'msg' => sprintf("操作成功"),
                'data' => null
            ]);
        } else {
            return response()->json([
                'code' => 1,
                'msg' => sprintf("操作失败"),
                'data' => null
            ]);
        }
    }

    /**
     * 充值次数
     *
     * @param Request $request
     * @return JsonResponse
     */
    public function rechargeTicket(Request $request) {
//        $validator = Validator::make($request->all(), [
//            'amount' => 'required|min:1',
//            'toUser' => 'required|min:1',
//        ], [
//            'required' => ':attribute 必填',
//        ]);
//
//        if ($validator->stopOnFirstFailure()->fails()) {
//            return response()->json([
//                'code' => 1,
//                'msg' => $validator->errors()->first(),
//                'data' => null
//            ]);
//        }

        $fromUser = $request->user();
        $toUser = User::find($request->toUser);
        if(empty($toUser)) {
            return response()->json([
                'code' => 1,
                'msg' => sprintf("目标账户不存在"),
                'data' => null
            ]);
        }

        $amount = (int) $request->amount;
        $amountRemove = (int) $request->amountRemove;
        $toUser->ticket =  $toUser->ticket + $amount - $amountRemove;
        $toUser->expired_at = date("Y-m-d H:i:s", strtotime("+1 month"));

        if($toUser->save()) {
            if($amount){
                BuyEvent::dispatch($toUser->id, $amount, sprintf("经办人 %s", $fromUser->name));
                if (!empty($toUser->parent)) {
                    $prize = round($amount * 0.1, 2, PHP_ROUND_HALF_DOWN);
                    $toUser->parent->money += $prize;
                    $toUser->parent->save();
                    PrizeDepositEvent::dispatch($toUser->parent_id, $prize,  sprintf("%s 充值提成", $toUser->name));
                }
            }
            return response()->json([
                'code' => 0,
                'msg' => sprintf("操作成功"),
                'data' => null
            ]);
        } else {
            return response()->json([
                'code' => 1,
                'msg' => sprintf("操作失败"),
                'data' => null
            ]);
        }
    }

    /**
     * 转出次数到指定账户
     *
     * @param Request $request
     * @return JsonResponse
     */
    public function  transferTicket(Request $request) {
        $validator = Validator::make($request->all(), [
            'amount' => 'required|min:1',
            'toUser' => 'required|min:1',
        ], [
            'required' => ':attribute 必填',
        ]);

        if ($validator->stopOnFirstFailure()->fails()) {
            return response()->json([
                'code' => 1,
                'msg' => $validator->errors()->first(),
                'data' => null
            ]);
        }

        $fromUser = $request->user();
        $toUser = User::find($request->toUser);
        if(empty($toUser)) {
            return response()->json([
                'code' => 1,
                'msg' => sprintf("目标账户不存在"),
                'data' => null
            ]);
        } else if($fromUser->id == $toUser->id) {
            return response()->json([
                'code' => 1,
                'msg' => sprintf("目标账户不能为自己"),
                'data' => null
            ]);
        }

        $amount = (int) $request->amount;
        if ($fromUser->ticket < $amount) {
            return response()->json([
                'code' => 1,
                'msg' => sprintf("可抢单次数不够! 当前为%s", $fromUser->ticket),
                'data' => null
            ]);
        }

        $fromUser->ticket = $fromUser->ticket - $amount;
        $toUser->ticket =  $toUser->ticket + $amount;
        $toUser->expired_at = date("Y-m-d H:i:s", strtotime("+1 month"));

        Log::info(sprintf("次数下拨，From %s To %s, 额度 %s", $fromUser->mobile, $toUser->mobile, $amount));
        if($fromUser->save() && $toUser->save()) {

            \App\Events\Ticket\TransferOutEvent::dispatch($fromUser->id, -$amount, sprintf("次数分拨给 %s", $toUser->name));
            \App\Events\Ticket\TransferInEvent::dispatch($toUser->id, $amount, sprintf("来自%s的次数分拨", $fromUser->name));

            return response()->json([
                'code' => 0,
                'msg' => sprintf("操作成功"),
                'data' => null
            ]);
        } else {
            return response()->json([
                'code' => 1,
                'msg' => sprintf("操作失败"),
                'data' => null
            ]);
        }
    }

    /**
     * 用户的标签
     *
     * @param Request $request
     * @return JsonResponse
     */
    public function tag(Request $request)
    {
        $user = $request->user();

        $tags = LoanTag::ofOwner($user)->select(["id","title"])->get();

        return response()->json([
            'code' => 0,
            'msg' => 'ok',
            'data' => [
                'items' => $tags,
            ]
        ]);
    }


    /**
     * @param Request $request
     * @return JsonResponse
     */
    public function saveTag(Request $request) {
        if (empty($request->title)) {
            return response()->json([
                'code' => 1,
                'msg' => '名称不能为空',
                'data' => null
            ]);
        }

        $user = $request->user();
        $model = LoanTag::ofOwner($user)->where('title', $request->title)->first();
        if(!empty($model)) {
            return response()->json([
                'code' => 0,
                'msg' => 'duplicate',
                'data' => [
                    'id' => $model->id,
                    'title' => $model->title,
                ]
            ]);
        }

        $model = new LoanTag();
        $model->title = $request->title;
        $model->org_root = $user->org_root;
        $model->org_code = $user->org_code;
        $model->user_id = $user->id;

        if ($model->save()) {
            return response()->json([
                'code' => 0,
                'msg' => 'ok',
                'data' => [
                    'id' => $model->id,
                    'title' => $model->title,
                ]
            ]);
        } else {
            return response()->json([
                'code' => 1,
                'msg' => '保存失败',
                'data' => null
            ]);
        }
    }

    /**
     * 充值订单
     *
     * @param Request $request
     * @return JsonResponse
     */
    public function depositOrder(Request $request) {
        $pageSize = (int) $request->input('pageSize', 20);
        $query = Order::with(['org', 'user'])->orderByDesc('id');

        if ($orderno = $request->orderno) {
            $query->where('orderno', $orderno);
        }

        if ($orgCode = $request->org_code) {
            $query->where('org_code', $orgCode);
        }

        if ($user_id = $request->user_id) {
            $query->where('user_id', $user_id);
        }

        if ($status = $request->input('status') ) {
            $query->where('status', intval($status));
        }

        return response()->json($query->paginate($pageSize));
    }

    /**
     * 提现订单
     *
     * @param Request $request
     * @return JsonResponse
     */
    public function moneyWithdraw(Request $request) {
        $pageSize = (int) $request->input('pageSize', 20);
        $query = UserMoneyWithdraw::with(['org', 'user'])->orderByDesc('id');

        if ($orgCode = $request->org_code) {
            $query->where('org_code', $orgCode);
        }

        if ($user_id = $request->user_id) {
            $query->where('user_id', $user_id);
        }

        if ($status = $request->input('status') ) {
            $query->where('status', intval($status));
        }

        return response()->json($query->paginate($pageSize));
    }

    /**
     * @param Request $request
     * @return JsonResponse
     */
    public function saveWithdrawStatus(Request $request) {

        $status = (int) $request->status;

        if ( !in_array($status,
            [UserMoneyWithdraw::PROCESSING, UserMoneyWithdraw::SUCCESS, UserMoneyWithdraw::FAIL])
        ) {
            return response()->json([
                'code' => 1,
                'msg' => sprintf("状态异常"),
                'data' => null
            ]);
        }

        $cnt = 0;
        foreach ($request->ids as $id) {
            $model = UserMoneyWithdraw::find($id);
            if (empty($model)) continue;
            if ($model->status != 0) continue;

            $model->status = $status;
            if (!empty($request->comment)) {
                $model->comment = $request->comment;
            }

            if ($model->save()) {
                if ($status == UserMoneyWithdraw::SUCCESS) {
                    $user = $model->user;
                    $user->money =  $user->money - $model->money;
                    $user->save();
                    WithdrawEvent::dispatch($model->user_id, -$model->money, sprintf("经办人 %s", $request->user()->name));
                }

                $cnt++;
            }
        }

        return response()->json([
            'code' => 0,
            'msg' => sprintf("成功更新%s条数据", $cnt),
            'data' => null
        ]);
    }
}
